home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1987
/
11
/
portlst.nov
< prev
next >
Wrap
Text File
|
1987-10-08
|
17KB
|
510 lines
Listing 1
/* VIDEO.I: Contains ROM BIOS video calls to be used in Turbo C */
#define ROM 0x10
union REGS inreg, outreg;
int videomode (int *ncols) /* get current display mode */
{ /* return number of cols via *ncols */
inreg.h.ah = 0x0F;
int86 (ROM, &inreg, &outreg);
*ncols = outreg.h.ah; /* number of cols */
return (outreg.h.al); /* return mode */
} /* ------------------------ */
int activepage (void) /* return active display page */
{
inreg.h.ah = 0x0F;
int86 (ROM, &inreg, &outreg);
return (outreg.h.bh);
} /* ------------------------ */
void setmode (int mode) /* set video mode */
{
inreg.h.al = mode;
inreg.h.ah = 0x00;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void setcursor (int start, int end) /* set cursor shape */
{
inreg.h.ch = start;
inreg.h.cl = end;
inreg.h.ah = 0x01;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
int curstart (void) /* get cursor starting line */
{
inreg.h.bh = 0; /* (cursor shape same in all pages */
inreg.h.ah = 0x03;
int86 (ROM, &inreg, &outreg);
return (outreg.h.ch);
} /* ------------------------ */
int cursend (void) /* get cursor ending line */
{
inreg.h.bh = 0;
inreg.h.ah = 0x03;
int86 (ROM, &inreg, &outreg);
return (outreg.h.cl);
} /* ------------------------ */
void cursoff (void) /* turn cursor off */
{
inreg.h.ch = curstart () | 0x10; /* turn on bit 4 */
inreg.h.cl = cursend ();
inreg.h.ah = 0x01;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void curson (void) /* turn cursor on */
{
inreg.h.ch = curstart () & 0x07; /* turn off high order bits */
inreg.h.cl = cursend ();
inreg.h.ah = 0x01;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void gotoxy (int col, int row, int page) /* set cursor pos */
{ /* must specify page */
inreg.h.bh = page;
inreg.h.dh = row;
inreg.h.dl = col;
inreg.h.ah = 0x02;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
int wherex (int page) /* return cursor column in page */
{
inreg.h.bh = page;
inreg.h.ah = 0x03;
int86 (ROM, &inreg, &outreg);
return (outreg.h.dl);
} /* ------------------------ */
int wherey (int page) /* return cursor row in page */
{
inreg.h.bh = page;
inreg.h.ah = 0x03;
int86 (ROM, &inreg, &outreg);
return (outreg.h.dh);
} /* ------------------------ */
void setpage (int page) /* set active display page */
{
inreg.h.al = page;
inreg.h.ah = 0x05;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void cls (void) /* clear active screen */
{
inreg.h.al = 25; /* entire screen */
inreg.h.bh = 0x07; /* set to gray on black */
inreg.h.ah = 0x06;
inreg.h.cl = 0; inreg.h.ch = 0;
inreg.h.dl = 79; inreg.h.dh = 24;
int86 (ROM, &inreg, &outreg);
gotoxy (0, 0, activepage ());
} /* ------------------------ */
void window (int x1, int y1, /* window upper left corner */
int x2, int y2, /* lower right corner */
char attrib) /* text attribute inside */
{
inreg.h.al = y2 - y1 + 1; /* clear entire window */
inreg.h.bh = attrib;
inreg.h.cl = x1; inreg.h.ch = y1;
inreg.h.dl = x2; inreg.h.dh = y2;
inreg.h.ah = 0x06;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void winScroll (int x1, int y1, int x2, int y2, /* scroll window */
int attr) /* one line upward */
{
inreg.h.al = 1;
inreg.h.cl = x1; inreg.h.ch = y1;
inreg.h.dl = x2; inreg.h.dh = y2;
inreg.h.bh = attr;
inreg.h.ah = 0x06;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
char chattr (int foregrnd, int backgrnd) /* character attrib*/
{
return ((backgrnd << 4) + foregrnd);
} /* ------------------------ */
char rdchara (int page, /* read char at curs pos */
char *attrib) /* return attribute indirectly */
{
inreg.h.bh = page;
inreg.h.ah = 0x08;
int86 (ROM, &inreg, &outreg);
*attrib = outreg.h.ah;
return (outreg.h.al);
} /* ------------------------ */
void wrtcha (char ch, char attrib, /* write char + attrib */
int page) /* at cursor pos on page */
{ /* NOTE: does not advance cursor */
inreg.h.al = ch;
inreg.h.bh = page;
inreg.h.bl = attrib;
inreg.x.cx = 1;
inreg.h.ah = 0x09;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void wrtstra (char *str, /* write string */
char attrib, /* with attribute */
int page) /* to page */
{ /* starting at cursor position */
int c, r, n, p = 0;
videomode (&n); /* get width of screen */
r = wherey (page); /* get current row */
while (str[p]) {
wrtcha (str[p++], attrib, page); /* write next char */
if ((c = wherex (page)) < (n - 1))
gotoxy (c + 1, r, page); /* advance cursor */
else
gotoxy (0, ++r, page); /* else wrap */
}
} /* ------------------------ */
void wrtch (char ch, int color, /* write char in color */
int page) /* at cursor position on page */
{
inreg.h.al = ch;
inreg.h.bl = color;
inreg.h.bh = page;
inreg.x.cx = 1;
inreg.h.ah = 0x0A;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void wrtstr (char *str, /* write string */
char color, /* in color */
int page) /* to page */
{ /* starting at cursor position */
int c, r, n, p = 0;
videomode (&n); /* get width of screen */
r = wherey (page); /* get current row */
while (str[p]) {
wrtcha (str[p++], color, page); /* write next char */
if ((c = wherex (page)) < (n - 1))
gotoxy (c + 1, r, page); /* advance cursor */
else
gotoxy (0, ++r, page); /* else wrap */
}
} /* ------------------------ */
void palette (int palno) /* set color palette */
{ /* valid only in mode 4 on CGA */
inreg.h.bh = 1;
inreg.h.bl = palno;
inreg.h.ah = 0x0B;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void graphbackground (int color) /* set graphics b/g color */
{
inreg.h.bh = 0;
inreg.h.bl = color;
inreg.h.ah = 0x0B;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
void plot (int x, int y, int pixel) /* plot pixel at x, y */
{
inreg.h.al = pixel; /* pixel (color) value */
inreg.h.bh = 0;
inreg.x.cx = x;
inreg.x.dx = y;
inreg.h.ah = 0x0C;
int86 (ROM, &inreg, &outreg);
} /* ------------------------ */
int pixel (int x, int y) /* return pixel value at x, y */
{
inreg.x.cx = x;
inreg.x.dx = y;
inreg.h.ah = 0x0D;
int86 (ROM, &inreg, &outreg);
return (outreg.h.al);
} /* ------------------------ */
Listing 2
/* VIDEO.H: Prototypes for contents of user-written VIDEO.LIB */
/* Describes calls to ROM BIOS video functions */
int videomode (int *ncols);
int activepage (void);
void setmode (int mode);
void setcursor (int start, int end);
int curstart (void);
int cursend (void);
void cursoff (void);
void curson (void);
void gotoxy (int col, int row, int page);
int wherex (int page);
int wherey (int page);
void setpage (int page);
void cls (void);
void window (int x1, int y1, int x2, int y2, char attrib);
char chattr (int fgrnd, int bgrnd);
char rdchara (int page, char *attr);
void wrtcha (char ch, char attr, int page);
void wrtstra (char *str, char attr, int page);
void wrtch (char ch, int color, int page);
void wrtstr (char *str, char color, int page);
void palette (int palno);
void graphbackground (int color);
void plot (int x, int y, int pixel);
int pixel (int x, int y);
Listing 3
/* DRAW.I: Draws lines in graphics mode */
/* hdraw draws horizontal line along y between x1 and x2 */
void hdraw (int x1, int x2, int y, int color)
{
int x;
if (x1 > x2) { /* sort x's into left-to-right order */
x = x1; x1 = x2; x2 = x;
}
for (x = x1; x <= x2; x++)
plot (x, y, color);
} /* ------------------------ */
/* vdraw draws vertical line along x between y1 and y2 */
void vdraw (int y1, int y2, int x, int color)
{
int y;
if (y1 > y2) { /* sort y's into top-to-bottom order */
y = y1; y1 = y2; y2 = y;
}
for (y = y1; y <= y2; y++)
plot (x, y, color);
} /* ------------------------ */
/* draw() does lines on the diagonal */
void draw (int x1, int y1, int x2, int y2, int color)
{
double xstep, ystep, xcum = 0.0, ycum = 0.0;
int dx, dy; /* deltas */
register x, y;
dx = x2 - x1;
dy = y2 - y1;
if (abs (dx) >= abs (dy)) { /* plot along x axis */
ystep = (double) dy / dx; /* movement along y axis per x */
if (dy < 0) { /* y travels to the left */
if (ystep > 0)
ystep *= -1; /* adjust for wrong sign from -y/-x */
} else /* y travels to the right */
if (ystep < 0)
ystep *= -1; /* adjust as above */
dx /= abs (dx); /* x increment */
for (x = x1, y = y1; x != x2; x += dx) {
plot (x, y, color);
ycum += ystep; /* cum motion along y axis */
y = y1 + ycum; /* next y */
}
} else { /* plot along y axis */
xstep = (double) dx / dy; /* movement along x axis per y */
if (dx < 0) {
if (xstep > 0)
xstep *= -1;
} else
if (xstep < 0)
xstep *= -1;
dy /= abs (dy); /* y increment */
for (y = y1, x = x1; y != y2; y += dy) {
plot (x, y, color);
xcum += xstep; /* cum motion along x axis */
x = x1 + xcum; /* next x */
}
}
} /* -------------------------- */
Listing 4
/* COLORS.H: Maps color names */
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define LIGHTGRAY 7
#define DARKGRAY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGENTA 13
#define YELLOW 14
#define WHITE 15
Listing 5
/* VID.C: Demos video functions */
/* TURBO C INCLUDES */
#include <stdio.h>
#include <bios.h>
#include <dos.h>
/* USER-WRITTEN INCLUDES */
#include <colors.h>
#include <video.i>
#include <draw.i>
/* LOCAL FUNCTION PROTOTYPES */
int vidIdent (int *vidmode);
void wait (void);
void stairsteps (void);
int isEGA (void);
void label (void);
void bigX (int adap, int vmode);
void hourglass (int adap, int vmode);
/* GLOBALS */
enum vidTypes {mda, cga, ega, compaq, other};
main ()
{
int adaptor, mode, cols;
cls (); /* clear screen */
adaptor = vidIdent (&mode); /* identify video adaptor */
if (adaptor != other) {
stairsteps (); /* cursor positioning demo */
bigX (adaptor, mode); /* graphics demo #1 */
hourglass (adaptor, mode); /* graphics demo #2 */
label ();
gotoxy (36, 12, 0);
puts ("All done!");
}
} /* ------------------------ */
int vidIdent (int *vidmode) /* identify video adaptor */
{
int flag, adap, width;
label (); /* label display */
puts ("\n\nDISPLAY INFORMATION:");
*vidmode = videomode (&width); /* get video mode */
flag = (biosequip () & 0x18) >> 4; /* get video eqpt flag */
if (isEGA ()) {
adap = ega;
puts ("\n\n Enhanced Graphics Adaptor");
} else
switch (flag) {
case 0: if (*vidmode == 2) {
adap = compaq;
puts ("\n\n Compaq adaptor");
} else {
adap = cga;
puts ("\n\n Color Graphics Adaptor");
}
break;
case 3: adap = mda;
puts ("\n\n Monochrome Display Adaptor");
break;
default: adap = other;
puts ("\n\n Adaptor not usable in this demo. Sorry.");
} /* end of switch */
printf ("\n Text screen size is %d columns x 25 rows\n", width);
if ((*vidmode < 4) || (*vidmode == 7))
puts ("\n Text mode currently active");
else
puts ("\n Graphics mode currently active");
wait ();
return (adap);
} /* ------------------------ */
int isEGA (void) /* determine if EGA is attached */
{ /* return TRUE if so, FALSE if not */
return (peekb (0x40, 0x87)); /* check EGA info byte */
} /* ------------------------ */
void wait (void) /* prompt to continue, wait for keypress */
{
int tab, width;
videomode (&width); /* get width in columns */
tab = (width - 33) / 2; /* starting column for text */
gotoxy (tab, 24, 0);
wrtstr ("Press any key to continue demo...", WHITE, 0);
getch ();
cls ();
} /* ------------------------ */
void label (void) /* label the screen at top center */
{
gotoxy (30, 0, 0);
wrtstra ("Video demonstration", chattr (YELLOW, BLUE), 0);
} /* ------------------------ */
void stairsteps (void)
{
int color = 1;
label ();
gotoxy (31, 2, 0); wrtstr ("Cursor positioning", LIGHTGRAY, 0);
gotoxy (10, 4, 0); wrtstr ("Stair", color++, 0);
gotoxy (20, 10, 0); wrtstr ("steps", color++, 0);
gotoxy (30, 16, 0); wrtstr ("going", color++, 0);
gotoxy (40, 22, 0); wrtstr ("down", color++, 0);
gotoxy (50, 16, 0); wrtstr ("and", color++, 0);
gotoxy (60, 10, 0); wrtstr ("back", color++, 0);
gotoxy (70, 4, 0); wrtstr ("up", color, 0);
wait ();
} /* ------------------------ */
void bigX (int vidAdap, int vmode) /* APA graphics demo #1 */
{ /* draws full-screen border and X, adjusting */
/* for EGA or CGA as indicated */
int x1 = 0, x2 = 639;
int y1 = 15, y2;
if ((vidAdap == mda) || (vidAdap == other)) /* can't do it */
return; /* so return with no action */
if (vidAdap == ega) { /* EGA demo: 640 x 350 (mode 0Fh) */
y2 = 349 - 15; /* set bottom of graphics screen */
setmode (0x0F); /* go to EGA mono graphics mode */
} else { /* CGA|Compaq demo: 640 x 200 (mode 06h) */
y2 = 199 - 15;
setmode (0x06);
}
label (); /* label the screen */
hdraw (x1, x2, y1, 1); /* draw line across top */
hdraw (x1, x2, y2, 1); /* then bottom */
vdraw (y1, y2, x1, 1); /* down left side */
vdraw (y1, y2, x2, 1); /* down right side */
draw (x1, y1, x2, y2, 1); /* main diagonal */
draw (x1, y2, x2, y1, 1); /* cross diagonal */
wait ();
setmode (vmode);
} /* ------------------------ */
void hourglass (int vidAdap, int vmode) /* graphics demo #2 */
{ /* operates in 320 x 200 four-color (CGA) mode */
int y, x1 = 60, x2 = 260, pixval = 1;
if ((vidAdap == mda) || (vidAdap == other)) /* can't do it */
return; /* so go back */
setmode (4); /* go to CGA graphics mode */
gotoxy (8, 0, 0);
puts ("320 x 200 color graphics"); /* show mode */
palette (0);
for (y = 50; y < 151; y++ ) { /* draw figure */
hdraw (x1, x2, y, pixval);
x1 += 2; x2 -= 2; /* change x's */
if (y == 84) pixval = 2; /* change colors */
if (y == 117) pixval = 3;
}
wait ();
setmode (vmode);
} /* ------------------------ */